class IOrder;

enum ErrorCode {
    OK,
    VolumnError,
    InstCodeError,
};

class OrderChecker {
public:
    int check(const IOrder & order) {
        if (false == checkVolumn(order)) return -ErrorCode::VolumnError;
        if (false == checkInstCode(order)) return -ErrorCode::InstCodeError ;
        //.......
        return 0;
    }
private:
    bool checkVolumn(const IOrder & order){
        return order.getVolumn() <= 0 ? false : true;
    }
    bool checkInstCode(const IOrder & order){
        return order.getInstCode().empty() ? false : true;
    }
};



class IOrder {
public:
    virtual const int getVolumn() const = 0;
    virtual const std::string & getInstCode() const = 0;
};





class OrderCheckerTest : public testing::Test {
protected:
    void test(const IOrder & order, ErrorCode erroCode){
        OrderChecker checker;
        int ret = checker.check(order);
        ASSERT_EQ(errorCode, ret);
    }
};

namespace test {

class AuTDOrder : public IOrder {
public:
    AuTDOrder(): instCode("Au(T+D)") {}
    const std::string & getInstCode() const {
        return instCode;
    }
private:
    std::string instCode;
};

class SuccessAuTDOrder : public AuTDOrder {
public:
    const int getVolumn() const override {
        return 10;
    }
};

} // end of namespace test
TEST_F(OrderCheckerTest, testSuccessOrder){
    SuccessOrder order;
    test(order, ErrorCode::OK);
}

namespace test {

class NoVolumnAuTDOrder : public  AuTDOrder{
public:
    const int getVolumn() const override {
        return -10;
    }
};

} // end of namespace test
TEST_F(OrderCheckerTest, testNoVolumnOrder){
    NoVolumnAuTDOrder order;
    test(order, ErrorCode::VolumnError);
}
